# -*- coding: utf-8 -*-
"""
Created on Fri Aug 11 11:18:40 2023

@author: 李小斌
"""
import os
import math
import numpy as np
from sklearn.model_selection import KFold
#from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.ensemble import BaggingRegressor
from sklearn.tree import ExtraTreeRegressor
from sklearn import neighbors
from sklearn import svm
from sklearn import tree
from sklearn import ensemble
from sklearn.metrics import mean_squared_error
import csv
#from gplearn import genetic
#from gplearn.genetic import SymbolicRegressor
#from datetime import datetime

dimension=400
    
def ontime(modelname,nfolds,datasetn):
    csv_reader=csv.reader(open('all'+str(dimension)+'.csv'))
    
    L1=[]
    y=[]                        #期末成绩,final
    #x=[]                       #平时所有数据
    xtest01=[]
    xtest02=[]
    xhomework01=[]
    xhomework02=[]
    xexperiment00=[]
    xexperiment01=[]
    xexperiment02=[]
    xexperiment03=[]
    xexperiment04=[]
    xexperiment05=[]
    xexperiment06=[]
    xexperiment07=[]
    xexperiment08=[]
    xexperiment09=[]
    xexperiment10=[]
    xexperiment11=[]
    xexperiment12=[]
    xexperiment13=[]
    xexperiment14=[]
    xexperiment15=[]
    xevaluation01=[]
    xevaluation02=[]
    xevaluation03=[]
    
    
    n=0
    for row in csv_reader:
        if n==0:
            n=n+1
            continue
        n=n+1
        y.append(row[1])                 #final
        xtest01.append(row[2])           #2次平时测验
        xtest02.append(row[3])
        xhomework01.append(row[5])      #2次作业
        xhomework02.append(row[4])
        xexperiment15.append(row[6])   #16次实验
        xexperiment14.append(row[7])
        xexperiment13.append(row[8])
        xexperiment12.append(row[9])
        xexperiment11.append(row[10])
        xexperiment10.append(row[11])
        xexperiment09.append(row[12])
        xexperiment08.append(row[13])
        xexperiment07.append(row[14])
        xexperiment06.append(row[15])
        xexperiment05.append(row[16])
        xexperiment04.append(row[17])
        xexperiment03.append(row[18])
        xexperiment02.append(row[19])
        xexperiment01.append(row[20])
        xexperiment00.append(row[21])
        xevaluation01.append(row[22:22+dimension])  #3次评价的语义嵌入
        xevaluation02.append(row[22+dimension:22+2*dimension])
        xevaluation03.append(row[22+2*dimension:22+3*dimension])
        

    
    #将所有数据转化为float类型数据
    ya=np.array(y,dtype=float)
    ya=ya/100
    
    xtest01a=np.array(xtest01,dtype=float)  
    xtest01a=xtest01a/100
    xtest01a=xtest01a.reshape(-1,1)
    
    xtest02a=np.array(xtest02,dtype=float)
    xtest02a=xtest02a/100
    xtest02a=xtest02a.reshape(-1,1)
    
    xhomework01a=np.array(xhomework01,dtype=float)
    xhomework01a=xhomework01a/100
    xhomework01a=xhomework01a.reshape(-1,1)
    
    xhomework02a=np.array(xhomework02,dtype=float) 
    xhomework02a=xhomework02a/100
    xhomework02a=xhomework02a.reshape(-1,1)
    
    xexperiment00a=np.array(xexperiment00,dtype=float)
    xexperiment00a=xexperiment00a/100
    xexperiment00a=xexperiment00a.reshape(-1,1)
    
    xexperiment01a=np.array(xexperiment01,dtype=float) 
    xexperiment01a=xexperiment01a/100
    xexperiment01a=xexperiment01a.reshape(-1,1)
    
    xexperiment02a=np.array(xexperiment02,dtype=float) 
    xexperiment02a=xexperiment02a/100
    xexperiment02a=xexperiment02a.reshape(-1,1)
    
    xexperiment03a=np.array(xexperiment03,dtype=float) 
    xexperiment03a=xexperiment03a/100
    xexperiment03a=xexperiment03a.reshape(-1,1)
    
    xexperiment04a=np.array(xexperiment04,dtype=float) 
    xexperiment04a=xexperiment04a/100
    xexperiment04a=xexperiment04a.reshape(-1,1)
    
    xexperiment05a=np.array(xexperiment05,dtype=float) 
    xexperiment05a=xexperiment05a/100
    xexperiment05a=xexperiment05a.reshape(-1,1)
    
    xexperiment06a=np.array(xexperiment06,dtype=float) 
    xexperiment06a=xexperiment06a/100
    xexperiment06a=xexperiment06a.reshape(-1,1)
    
    xexperiment07a=np.array(xexperiment07,dtype=float) 
    xexperiment07a=xexperiment07a/100
    xexperiment07a=xexperiment07a.reshape(-1,1)
    
    xexperiment08a=np.array(xexperiment08,dtype=float) 
    xexperiment08a=xexperiment08a/100
    xexperiment08a=xexperiment08a.reshape(-1,1)
    
    xexperiment09a=np.array(xexperiment09,dtype=float) 
    xexperiment09a=xexperiment09a/100
    xexperiment09a=xexperiment09a.reshape(-1,1)
    
    xexperiment10a=np.array(xexperiment10,dtype=float) 
    xexperiment10a=xexperiment10a/100
    xexperiment10a=xexperiment10a.reshape(-1,1)
    
    xexperiment11a=np.array(xexperiment11,dtype=float) 
    xexperiment11a=xexperiment11a/100
    xexperiment11a=xexperiment11a.reshape(-1,1)
    
    xexperiment12a=np.array(xexperiment12,dtype=float) 
    xexperiment12a=xexperiment12a/100
    xexperiment12a=xexperiment12a.reshape(-1,1)
    
    xexperiment13a=np.array(xexperiment13,dtype=float) 
    xexperiment13a=xexperiment13a/100
    xexperiment13a=xexperiment13a.reshape(-1,1)
    
    xexperiment14a=np.array(xexperiment14,dtype=float) 
    xexperiment14a=xexperiment14a/100
    xexperiment14a=xexperiment14a.reshape(-1,1)
    
    xexperiment15a=np.array(xexperiment15,dtype=float) 
    xexperiment15a=xexperiment15a/100
    xexperiment15a=xexperiment15a.reshape(-1,1)
    
    xevaluation01a=np.array(xevaluation01,dtype=float) 
    xevaluation02a=np.array(xevaluation02,dtype=float)   
    xevaluation03a=np.array(xevaluation03,dtype=float)   
      

    """
    datasetn表示参与训练预测的X集合,按照结束时间排序
    
1	Experiment0	2023/3/14
2	Experiment1	2023/3/21
3	Experiment2	2023/3/28
4	Experiment3	2023/4/4
5	Experiment4	2023/4/11
6	Evaluation1	2023/4/13
7	Test1	2023/4/14
8	Experiment5	2023/4/18
9	Homework1	2023/4/25
10	Experiment6	2023/4/28
11	Homework2	2023/5/9
12	Experiment7	2023/5/9
13	Experiment8	2023/5/16
14	Test2	2023/5/19
15	Experiment9	2023/5/19
16	Experiment10	2023/5/23
17	Experiment11	2023/5/26
18	Experiment12	2023/5/30
19	Experiment13	2023/6/2
20	Evaluation2	2023/6/2
21	Evaluation3	2023/6/2
22	Experiment14	2023/6/6
23	Experiment15	2023/6/9
24	Exam	2023/6/30

    """
    
    xa=np.array([])
    while True:
       xa=xexperiment00a      
       if datasetn==1:
           break
       xa=np.hstack((xa,xexperiment01a))
       if datasetn==2:
           break
       xa=np.hstack((xa,xexperiment02a))
       if datasetn==3:
           break
       xa=np.hstack((xa,xexperiment03a))
       if datasetn==4:
           break
       xa=np.hstack((xa,xexperiment04a))
       if datasetn==5:
           break
       xa=np.hstack((xa,xevaluation01a))
       if datasetn==6:
           break
       xa=np.hstack((xa,xtest01a))
       if datasetn==7:
           break
       xa=np.hstack((xa,xexperiment05a))
       if datasetn==8:
           break
       xa=np.hstack((xa,xhomework01a))
       if datasetn==9:
           break
       xa=np.hstack((xa,xexperiment06a))
       if datasetn==10:
           break
       xa=np.hstack((xa,xhomework02a))
       if datasetn==11:
           break
       xa=np.hstack((xa,xexperiment07a))
       if datasetn==12:
           break
       xa=np.hstack((xa,xexperiment08a))
       if datasetn==13:
           break
       xa=np.hstack((xa,xtest02a))
       if datasetn==14:
           break
       xa=np.hstack((xa,xexperiment09a))
       if datasetn==15:
           break
       xa=np.hstack((xa,xexperiment10a))
       if datasetn==16:
           break
       xa=np.hstack((xa,xexperiment11a))
       if datasetn==17:
           break
       xa=np.hstack((xa,xexperiment12a))
       if datasetn==18:
           break
       xa=np.hstack((xa,xexperiment13a))
       if datasetn==19:
           break
       xa=np.hstack((xa,xevaluation02a))
       if datasetn==20:
           break
       xa=np.hstack((xa,xevaluation03a))
       if datasetn==21:
           break
       xa=np.hstack((xa,xexperiment14a))
       if datasetn==22:
           break
       xa=np.hstack((xa,xexperiment15a))
       if datasetn==23:
           break
       
    
    """
    #数据预处理
    ya=ya/100
    for i in range(xexperimenta.shape[0]):
        for j in range(xexperimenta.shape[1]):
            if xexperimenta[i][j]==100:
                xexperimenta[i][j]=1
            else:
                xexperimenta[i][j]=0
   """             
    #nfolds=5
    kf = KFold(n_splits=nfolds,shuffle=False)  # 初始化KFold
    if modelname=='LR':
        model = LinearRegression()
    elif modelname=='Ridge':
        model = Ridge(alpha=.5)
    elif modelname=='Lasso':
        model=Lasso(alpha=.5)
    elif modelname=='SVR':
        model=svm.SVR()
    elif modelname=='DT':
        model=tree.DecisionTreeRegressor()
    elif modelname=='KNN':
        model=neighbors.KNeighborsRegressor()
    elif modelname=='RandomForest':
        model=ensemble.RandomForestRegressor(n_estimators=20)
    elif modelname=='Adaboost':
        model=ensemble.AdaBoostRegressor(n_estimators=20)
    elif modelname=='GBRT':
        model=ensemble.GradientBoostingRegressor(n_estimators=20)
    elif modelname=='Bagging':
        model=BaggingRegressor()
    elif modelname=='ExtraTree':
        model=ExtraTreeRegressor()
    #model用于预测测验，model1用于预测作业,model2用于预测实验，model3用于预测评价
    #model4用于合并预测

    for train_index , test_index in kf.split(ya):  # 调用split方法切分数据        
        #rmse0:只有测试
        model.fit(xa[train_index],ya[train_index])
        ypt0=model.predict(xa[test_index])
        rmse=math.sqrt(mean_squared_error(ya[test_index],ypt0))    
        
        L1.append(rmse)  #准备保存哪一种结果，最后对应哪一种的数据  
    return [L1]

def evaluate(modelname,ntimes,nfolds,datasetn):
    file=open(modelname+'.csv','w',newline='')       
    f_csv=csv.writer(file)
    header=['rmse']
    f_csv.writerow(header)
    times=0
    while times<ntimes:
        L=ontime(modelname,nfolds,datasetn)
        Lw=[]           #用于获取L1-L8中相同位置的rmse，构造成一个list存入csv    
        for pos in range(0,nfolds):
            for Litem in L:
                Lw.append(Litem[pos])
            f_csv.writerow(Lw)
            Lw=[]
        times+=1
    file.close()

def getRmse(modelname):
    filepath=modelname+'.csv'
    file=open(filepath)
    csv_reader=csv.reader(file)    
    x=[]
    n=0
    for row in csv_reader:
        if n==0:
            n=n+1
            continue
        n=n+1
        x.append(row[0])                    
    #将所有数据转化为float类型数据
    file.close()
    os.remove(filepath)
    xa=np.array(x,dtype=float)
    return np.mean(xa)

def getCompare():
      #模型名称，LR,Ridge,Lasso,SVR,DT,KNN,RandomForest,Adaboost,GBRT,Bagging,ExtraTree
    ntimes=20#运行总次数
    nfolds=5#fold的次数
    modelnames=['LR','Ridge','Lasso','SVR','DT','KNN','RandomForest',
                'Adaboost','GBRT','Bagging','ExtraTree']
    """
    datasetn表示参与训练预测的X集合
    
    one->1:test 2:homework 3:experiment 4:evaluation 
    
    two->5:test+homwork 6:test+experiment 7:test+evaluation 8:homework+experiment
    9:homework+evaluation 10:experiment+evaluation
    
    three->11:test+homework+experiment 12:test+homework+evaluation 
    13:test+experiemnt+evaluation 14:homework+experiment+evaluation
    
    for->15:test+homework+experiment+evaluation    
    """
    DatasetN=23
    Rtotal=[]
    Rtmp=[]
    for datasetn in range(1,DatasetN+1):
        for modelname in modelnames:
            evaluate(modelname,ntimes,nfolds,datasetn)
            v=getRmse(modelname)
            Rtmp.append(v)
        Rtotal.append(Rtmp)
        Rtmp=[]
    Rtotala=np.array(Rtotal)
    Rtotala=np.transpose(Rtotala)
    Rtotal=Rtotala.tolist()
    file=open('timelyregression_compare'+str(dimension)+'.csv','w',newline='')  
    f_csv=csv.writer(file)
    header=['method']
    for col in range(1,DatasetN+1):
        header.append(col)
    f_csv.writerow(header)
    i=0
    for modelname in modelnames:
        temp=[modelname]
        for col in range(0,DatasetN):
            temp.append(Rtotal[i][col])
        f_csv.writerow(temp)
        i=i+1
    file.close() 


if __name__=="__main__":
    getCompare()
    os.system('shutdown /s /t 120')  